#pragma once

#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <vector>

#define NUM 8

//环形生消模型
template<class T>
class Ringqueue{
    //PV操作
    private:
    void P(sem_t &sem){sem_wait(&sem);}
    void V(sem_t &sem){sem_post(&sem);}
    public:
    Ringqueue(int cap = NUM):_cap(cap),_p_pos(0),_c_pos(0){
        //初始化
        _rq.reserve(_cap);
        sem_init(&_blank_sem,0,_cap);
        sem_init(&_data_sem,0,0);
    }
    ~Ringqueue(){
        sem_destroy(&_blank_sem);
        sem_destroy(&_data_sem);
    }
    //生产
    void Push(const T& data){
        //将数据放入环形队列中
        P(_blank_sem);
        _rq[_p_pos] = data;
        V(_data_sem);
        //此时生产者要往后走了，
        _p_pos++;
        _p_pos %= _cap;
    }
    void Pop(T& data){
        //将数据放入环形队列中
        P(_data_sem);
        data = _rq[_c_pos];
        V(_blank_sem);
        //此时生产者要往后走了，
        _c_pos++;
        _c_pos %= _cap;
    }
    //消费
    private:
    std::vector<T> _rq; //环形队列
    int _cap;//容量
    int _p_pos; //生产者位置
    int _c_pos; //消费者位置
    sem_t _blank_sem;//空间信号量
    sem_t _data_sem;//数据信号量
};